1 R nerede kullanılır

  • Veri düzenleme
  • İstatistik analiz
  • Web sayfası hazırlama (Statik/Dinamik)
  • Sunum hazırlama
  • Programlama
  • Otomatik, periodik ve tekrarlanabilir rapor hazırlama
  • pdf, html, ppt oluşturma
  • tez yazma
  • kitap yazma
  • CV oluşturma
  • poster hazırlama
  • rapor şablonu oluşturma

2 R generation

R yıllar içinde çok fazla değişim gösterdi

https://rss.onlinelibrary.wiley.com/doi/10.1111/j.1740-9713.2018.01169.x

:scale 30%


3 R yükleme

http://www.youtube.com/watch?v=XcBLEVknqvY

What is R?


3.2 RStudio


3.2.2 RStudio


3.2.3 RStudio eklentileri

  • Discover and install useful RStudio addins

https://cran.r-project.org/web/packages/addinslist/README.html

https://rstudio.github.io/rstudioaddins/

devtools::install_github("rstudio/addinexamples", type = "source")

3.3 MacOS için

4 R zor şeyler için kolay, kolay şeyler için zor

R Syntax Comparison::CHEAT SHEET

https://www.amelia.mn/Syntax-cheatsheet.pdf



5 R paketleri

5.1 Neden paketler var




5.3 Kendi paket evrenini oluştur


5.4 R paket yükleme

install.packages("tidyverse", dependencies = TRUE)
install.packages("jmv", dependencies = TRUE)
install.packages("questionr", dependencies = TRUE)
install.packages("Rcmdr", dependencies = TRUE)
install.packages("summarytools")
# install.packages("tidyverse", dependencies = TRUE)
# install.packages("jmv", dependencies = TRUE)
# install.packages("questionr", dependencies = TRUE)
# install.packages("Rcmdr", dependencies = TRUE)
# install.packages("summarytools")

5.5 Paket çağırma

# require(tidyverse)  
# require(jmv)  
# require(questionr)  
# library(summarytools)  
# library(gganimate)  

6 R için yardım bulma

# ?mean
# ??efetch
# help(merge)
# example(merge)

  • Vignette

:scale 80%


https://stackoverflow.com/

  • Google uygun anahtar kelime



  • Google’da ararken [R] yazmak da işe yarayabiliyor.

  • searcher package 📦


http://cran.r-project.org/doc/contrib/Baggott-refcard-v2.pdf

https://www.rstudio.com/resources/cheatsheets/

  • Awesome R

https://github.com/qinwf/awesome-R#readme

https://awesome-r.com/

  • Twitter

https://twitter.com/hashtag/rstats?src=hash


  • Use Reproducible Examples When Asking

8 RStudio ile veri yükleme

https://support.rstudio.com/hc/en-us/articles/218611977-Importing-Data-with-RStudio


8.1 Excel

8.2 SPSS

8.3 CSV


9 Veriyi görüntüleme


10 Veriyi görüntüleme

# library(nycflights13)
# summary(flights)
View(data)
data
head
tail
glimpse
str
skimr::skim()

11 Veriyi değiştirme

11.1 Veriyi kod ile değiştirelim

11.2 Veriyi eklentilerle değiştirme

:scale 30%


11.3 RStudio aracılığıyla recode

questionr paketi kullanılacak

:scale 30%


https://juba.github.io/questionr/articles/recoding_addins.html




12 Basit tanımlayıcı istatistikler

summary()
mean
median
min
max
sd
table()

library(readr)
irisdata <- read_csv("data/iris.csv")

jmv::descriptives(
    data = irisdata,
    vars = "Sepal.Length",
    splitBy = "Species",
    freq = TRUE,
    hist = TRUE,
    dens = TRUE,
    bar = TRUE,
    box = TRUE,
    violin = TRUE,
    dot = TRUE,
    mode = TRUE,
    sum = TRUE,
    sd = TRUE,
    variance = TRUE,
    range = TRUE,
    se = TRUE,
    skew = TRUE,
    kurt = TRUE,
    quart = TRUE,
    pcEqGr = TRUE)

# install.packages("scatr")
scatr::scat(
    data = irisdata,
    x = "Sepal.Length",
    y = "Sepal.Width",
    group = "Species",
    marg = "dens",
    line = "linear",
    se = TRUE)

12.1 summarytools

https://cran.r-project.org/web/packages/summarytools/vignettes/Introduction.html

library(summarytools)
summarytools::freq(iris$Species, style = "rmarkdown")

summarytools::freq(iris$Species, report.nas = FALSE, style = "rmarkdown", headings = FALSE)

with(tobacco, print(ctable(smoker, diseased), method = 'render'))

with(tobacco,
     print(ctable(smoker, diseased, prop = 'n', totals = FALSE),
           omit.headings = TRUE, method = "render"))

summarytools::descr(iris, style = "rmarkdown")

descr(iris,
      stats = c("mean", "sd", "min", "med", "max"),
      transpose = TRUE,
      headings = FALSE,
      style = "rmarkdown")

# view(dfSummary(iris))


# First save the results
iris_stats_by_species <- by(data = iris,
                            INDICES = iris$Species,
                            FUN = descr, stats = c("mean", "sd", "min", "med", "max"),
                            transpose = TRUE)
# Then use view(), like so:
view(iris_stats_by_species, method = "pander", style = "rmarkdown")

# view(iris_stats_by_species)


data(tobacco) # tobacco is an example dataframe included in the package
BMI_by_age <- with(tobacco,
                   by(BMI, age.gr, descr,
                      stats = c("mean", "sd", "min", "med", "max")))
view(BMI_by_age, "pander", style = "rmarkdown")

BMI_by_age <- with(tobacco,
                   by(BMI, age.gr, descr,  transpose = TRUE,
                      stats = c("mean", "sd", "min", "med", "max")))

view(BMI_by_age, "pander", style = "rmarkdown", omit.headings = TRUE)

what.is(iris)

12.2 skimr

library(skimr)
skim(df)

12.3 DataExplorer

library(DataExplorer)
DataExplorer::create_report(df)


12.5 Grafikler

# library(ggplot2)
# library(mosaic)
# mPlot(irisdata)
descr(tobacco, style = 'rmarkdown')

print(descr(tobacco), method = 'render', table.classes = 'st-small')

dfSummary(tobacco, style = 'grid', plain.ascii = FALSE)

print(dfSummary(tobacco, graph.magnif = 0.75), method = 'render')



13 Bazı arayüzler

https://sbalci.github.io/MyRCodesForDataAnalysis/R-Arayuzler.nb.html


13.1 Rcmdr

library(Rcmdr)

Rcmdr::Commander()
  • A Comparative Review of the R Commander GUI for R

http://r4stats.com/articles/software-reviews/r-commander/


15 Sonraki Konular

  • RStudio ile GitHub kullanımı
  • R Markdown ve R Notebook ile tekrarlanabilir rapor
  • Hipotez testleri

16 Geri Bildirim



17 Libraries Used

citation()
citation("tidyverse")
citation("foreign")
citation("tidylog")
citation("janitor")
citation("jmv")
citation("tangram")
citation("finalfit")
citation("summarytools")
citation("ggstatplot")
citation("readxl")
sessionInfo()

18 İletişim

Completed on 2019-09-24 22:55:33.

Serdar Balci, MD, Pathologist

https://rpubs.com/sbalci/CV
https://sbalci.github.io/
https://github.com/sbalci
https://twitter.com/serdarbalci


CommitMessage <- paste("updated on ", Sys.time(), sep = "")

wd <- getwd()

gitCommand <- paste("cd ", wd, " \n git add . \n git commit --message '", CommitMessage, "' \n git push origin master \n", sep = "")

system(command = gitCommand, intern = TRUE
)

  1. Bu bir derlemedir, mümkün mertebe alıntılara referans vermeye çalıştım.↩︎

LS0tCnRpdGxlOiBSIGlsZSBhbmFsaXplIGJhxZ9sYXJrZW5eW0J1IGJpciBkZXJsZW1lZGlyLCBtw7xta8O8biBtZXJ0ZWJlIGFsxLFudMSxbGFyYSByZWZlcmFucwogIHZlcm1leWUgw6dhbMSxxZ90xLFtLl0KYXV0aG9yOiAiRGVybGV5ZW4gW1NlcmRhciBCYWxjxLEsIE1ELCBQYXRob2xvZ2lzdF0oaHR0cHM6Ly9zYmFsY2kuZ2l0aHViLmlvLykiCmluc3RpdHV0ZTogIltzZXJkYXJiYWxjaS5jb21dKGh0dHBzOi8vd3d3LnNlcmRhcmJhbGNpLmNvbSkiCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSlgIgpvdXRwdXQ6CiAgeGFyaW5nYW46Om1vb25fcmVhZGVyOgogICAgbGliX2RpcjogbGlicwogICAgbmF0dXJlOgogICAgICBiZWZvcmVJbml0OiBbIm1hY3Jvcy5qcyIsICJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiXQogICAgICBoaWdobGlnaHRTdHlsZTogZ2l0aHViCiAgICAgIGhpZ2hsaWdodExpbmVzOiB0cnVlCiAgICAgIGNvdW50SW5jcmVtZW50YWxTbGlkZXM6IGZhbHNlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHJldmVhbGpzOjpyZXZlYWxqc19wcmVzZW50YXRpb246CiAgaHRtbF9ub3RlYm9vazoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGhpZ2hsaWdodDoga2F0ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRoZW1lOiBmbGF0bHkKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogeWVzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzUnCiAgaHRtbF9kb2N1bWVudDoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGtlZXBfbWQ6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQogICAgdG9jX2Zsb2F0OiB5ZXMKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgo8IS0tIE9wZW4gYWxsIGxpbmtzIGluIG5ldyB0YWItLT4gIAo8YmFzZSB0YXJnZXQ9Il9ibGFuayIvPiAgIAoKPCEtLSBHbyB0byB3d3cuYWRkdGhpcy5jb20vZGFzaGJvYXJkIHRvIGN1c3RvbWl6ZSB5b3VyIHRvb2xzIC0tPiA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSIvL3M3LmFkZHRoaXMuY29tL2pzLzMwMC9hZGR0aGlzX3dpZGdldC5qcyNwdWJpZD1yYS01YmMzNjkwMGE0MDUwOTBiIj4gIAo8L3NjcmlwdD4KCjwhLS0gWyFbXShodHRwOi8vcmVzLmNsb3VkaW5hcnkuY29tL2R5ZDkxMWttaC9pbWFnZS91cGxvYWQvZl9hdXRvLHFfYXV0bzpiZXN0L3YxNTMwMTEzMDc3L0ltYWdlXzJfdmZ5NDhiLnBuZyldKGh0dHBzOi8vd3d3LmRhdGFjYW1wLmNvbS9jb21tdW5pdHkvdHV0b3JpYWxzL2RhdGEtc2NpZW5jZS1waXRmYWxscykgLS0+CgoKYGBge3Igc2V0dXAgZ2xvYmFsIGNodW5rIHNldHRpbmdzLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCgltZXNzYWdlID0gRkFMU0UsCgl3YXJuaW5nID0gRkFMU0UsCgljb21tZW50ID0gTkEsCglpbmNsdWRlID0gRkFMU0UsCgl0aWR5ID0gVFJVRQopCmBgYAoKCiMgUiBuZXJlZGUga3VsbGFuxLFsxLFyCgotIFZlcmkgZMO8emVubGVtZQotIMSwc3RhdGlzdGlrIGFuYWxpegotIFdlYiBzYXlmYXPEsSBoYXrEsXJsYW1hIChTdGF0aWsvRGluYW1paykKLSBTdW51bSBoYXrEsXJsYW1hCi0gUHJvZ3JhbWxhbWEKLSBPdG9tYXRpaywgcGVyaW9kaWsgdmUgdGVrcmFybGFuYWJpbGlyIHJhcG9yIGhhesSxcmxhbWEKLSBwZGYsIGh0bWwsIHBwdCBvbHXFn3R1cm1hCi0gdGV6IHlhem1hCi0ga2l0YXAgeWF6bWEKLSBDViBvbHXFn3R1cm1hCi0gcG9zdGVyIGhhesSxcmxhbWEKLSByYXBvciDFn2FibG9udSBvbHXFn3R1cm1hCi0gLi4uCgotLS0KCiMgUiBnZW5lcmF0aW9uCgpSIHnEsWxsYXIgacOnaW5kZSDDp29rIGZhemxhIGRlxJ9pxZ9pbSBnw7ZzdGVyZGkKCmh0dHBzOi8vcnNzLm9ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS8xMC4xMTExL2ouMTc0MC05NzEzLjIwMTguMDExNjkueAoKIVtdKGh0dHBzOi8vd29sLXByb2QtY2RuLmxpdGVyYXR1bW9ubGluZS5jb20vcGItYXNzZXRzL2pvdXJuYWwtYmFubmVycy8xNzQwOTcxMy0xNTAxMzg0NzU2MDM3LmpwZykKCiFbOnNjYWxlIDMwJV0oaHR0cHM6Ly93b2wtcHJvZC1jZG4ubGl0ZXJhdHVtb25saW5lLmNvbS9jbXMvYXR0YWNobWVudC8xYTQ5YzA3Yi1iNTZmLTQzMjctOGU5Mi03ODI3ZWY1MWE3YmIvc2lnbjExNjktZ3JhLTAwMDItbS5qcGcpCgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aCA9ICJodHRwczovL3dvbC1wcm9kLWNkbi5saXRlcmF0dW1vbmxpbmUuY29tL2Ntcy9hdHRhY2htZW50LzFhNDljMDdiLWI1NmYtNDMyNy04ZTkyLTc4MjdlZjUxYTdiYi9zaWduMTE2OS1ncmEtMDAwMi1tLmpwZyIpCmBgYAoKCi0tLQoKIyBSIHnDvGtsZW1lCgpodHRwOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WGNCTEVWa25xdlkKCgohW1doYXQgaXMgUj9dKGh0dHA6Ly9pbWcueW91dHViZS5jb20vdmkvWGNCTEVWa25xdlkvMC5qcGcpCgoKLS0tCgoKIyMgUi1wcm9qZWN0CgpodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy8KCi0tLQoKIyMgUlN0dWRpbwoKCiFbXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vdGFsa3MvbmVzcy1pbmZlci9pbWcvZW5naW5lLnBuZykKCi0tLQoKIyMjIFJTdHVkaW8KCltodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9dKGh0dHBzOi8vd3d3LnJzdHVkaW8uY29tLykKCltodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9wcm9kdWN0cy9yc3R1ZGlvL2Rvd25sb2FkL10oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC8pCgpbaHR0cHM6Ly9tb2Rlcm5kaXZlLmNvbS8yLWdldHRpbmctc3RhcnRlZC5odG1sXShodHRwczovL21vZGVybmRpdmUuY29tLzItZ2V0dGluZy1zdGFydGVkLmh0bWwpCgotLS0KCiMjIyBSU3R1ZGlvCgoKWyFbXShodHRwOi8vd3d3LXVzZXJzLnlvcmsuYWMudWsvfmVyMTMvUlN0dWRpbyUyMEFuYXRvbXkuc3ZnKV0oaHR0cHM6Ly9idXp6cmJlZWxpbmUuYmxvZy8yMDE4LzA3LzA0L3JzdHVkaW8tYW5hdG9teS8pCgoKCi0tLQoKIyMjIFJTdHVkaW8gZWtsZW50aWxlcmkKCi0gRGlzY292ZXIgYW5kIGluc3RhbGwgdXNlZnVsIFJTdHVkaW8gYWRkaW5zCgpodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvYWRkaW5zbGlzdC9SRUFETUUuaHRtbAoKaHR0cHM6Ly9yc3R1ZGlvLmdpdGh1Yi5pby9yc3R1ZGlvYWRkaW5zLwoKCmBgYApkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInJzdHVkaW8vYWRkaW5leGFtcGxlcyIsIHR5cGUgPSAic291cmNlIikKYGBgCgoKLS0tCgojIyBNYWNPUyBpw6dpbgoKIyMjIFgxMQoKaHR0cHM6Ly93d3cueHF1YXJ0ei5vcmcvCgojIyMgSmF2YSBPUwoKaHR0cHM6Ly9zdXBwb3J0LmFwcGxlLmNvbS9rYi9kbDE1NzIKCi0tLQoKCiMgUiB6b3IgxZ9leWxlciBpw6dpbiBrb2xheSwga29sYXkgxZ9leWxlciBpw6dpbiB6b3IKCgotIFtSIG1ha2VzIGVhc3kgdGhpbmdzIGhhcmQsIGFuZCBoYXJkIHRoaW5ncyBlYXN5XShodHRwOi8vcjRzdGF0cy5jb20vYXJ0aWNsZXMvd2h5LXItaXMtaGFyZC10by1sZWFybi8pCgoKLSBBeW7EsSDFn2V5aSDDp29rIGZhemxhIMWfZWtpbGRlIHlhcG1hayBtw7xta8O8bgoKUiBTeW50YXggQ29tcGFyaXNvbjo6Q0hFQVQgU0hFRVQKCmh0dHBzOi8vd3d3LmFtZWxpYS5tbi9TeW50YXgtY2hlYXRzaGVldC5wZGYKCgotLS0KCgo8YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj48YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvUlN0YXRzP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jUlN0YXRzPC9hPiDigJQgVGhlcmUgYXJlIGFsd2F5cyBzZXZlcmFsIHdheXMgdG8gZG8gdGhlIHNhbWUgdGhpbmcuLi4gbmljZSBleGFtcGxlIG9uIHdpdGggdGhlIGlkZW50aXR5IG1hdHJpeCBieSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL1RlYVN0YXRzP3JlZl9zcmM9dHdzcmMlNUV0ZnciPkBUZWFTdGF0czwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90LmNvL08zR1hkUGlNMzIiPmh0dHBzOi8vdC5jby9PM0dYZFBpTTMyPC9hPjwvcD4mbWRhc2g7IENvbGluIEZheSDwn6SYIChAX0NvbGluRmF5KSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL19Db2xpbkZheS9zdGF0dXMvMTExMjc0NjYzMzQ2NzUxODk3Nz9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5BcHJpbCAxLCAyMDE5PC9hPjwvYmxvY2txdW90ZT4KPHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PgoKLS0tCgoKIyBSIHBha2V0bGVyaQoKCiMjIE5lZGVuIHBha2V0bGVyIHZhcgoKWyFbXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vdGFsa3MvbmVzcy1pbmZlci9pbWcvYXBwc3RvcmUucG5nKV0oaHR0cHM6Ly9pc21heWMuZ2l0aHViLmlvL3RhbGtzL25lc3MtaW5mZXIvc2xpZGVfZGVjay5odG1sIzcpCgotLS0KCjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD48YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5JIGxvdmUgdGhlIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHM8L2E+IGNvbW11bml0eS48YnI+U29tZW9uZSBpcyBsaWtlLCAmcXVvdDtvaCBoZXkgcGVlcHMsIEkgc2F3IGEgYmlnIG5lZWQgZm9yIHRoaXMgbXVuZGFuZSBidXQgZGlmZmljdWx0IHRhc2sgdGhhdCBJIGluZnJlcXVlbnRseSBkbywgc28gSSBjcmVhdGVkIGEgcGFja2FnZSB0aGF0IHdpbGwgbGl0ZXJhbGx5IHNjcmFwZSB0aGUgbGFzdCBiaXRzIG9mIHBlYW51dCBidXR0ZXIgb3V0IG9mIHRoZSBqYXIgZm9yIHlvdS4gSXQmIzM5O3MgY2FsbGVkIHBicGx5ci4mcXVvdDs8YnI+V2hhdCBhIHRyaWJlLjwvcD4mbWRhc2g7IEZyYW5rIEVsYXZza3kg4bSw4bWD4bWX4bWDIOG1guG2puG2u+G1g8qz4bWIIChARnJhbmtseV9EYXRhKSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL0ZyYW5rbHlfRGF0YS9zdGF0dXMvMTAxNDE4OTA5NTI5NDI5MTk2OD9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5KdWx5IDMsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPgoKPCEtLSAtLS0gLS0+Cgo8IS0tIGh0dHBzOi8vYmxvZy5taXRjaGVsbG9oYXJhd2lsZC5jb20vYmxvZy91c2VyLTIwMTgtZmVhdHVyZS13YWxsLyAtLT4KCi0tLQoKIVtdKGh0dHBzOi8vYmxvZy5taXRjaGVsbG9oYXJhd2lsZC5jb20vYmxvZy8yMDE4LTA3LTExLXVzZXItMjAxOC1mZWF0dXJlLXdhbGxfZmlsZXMvZmluYWwuanBnKQoKLS0tCgojIyBQYWtldGxlcmkgbmVyZWRlbiBidWxhYmlsaXJpegoKLSBBdmFpbGFibGUgQ1JBTiBQYWNrYWdlcyBCeSBOYW1lICAKaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2F2YWlsYWJsZV9wYWNrYWdlc19ieV9uYW1lLmh0bWwKCi0gQ1JBTiBUYXNrIFZpZXdzICAKaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3ZpZXdzLwoKLSBCaW9jb25kdWN0b3IgIApodHRwczovL3d3dy5iaW9jb25kdWN0b3Iub3JnCgotIFJlY29tbWVuZFIgIApodHRwOi8vcmVjb21tZW5kci5pbmZvLwoKLSBwa2dzZWFyY2ggIApDUkFOIHBhY2thZ2Ugc2VhcmNoICAKaHR0cHM6Ly9naXRodWIuY29tL21ldGFjcmFuL3BrZ3NlYXJjaAoKLSBDUkFOc2VhcmNoZXIgIApodHRwczovL2dpdGh1Yi5jb20vUmhvSW5jL0NSQU5zZWFyY2hlciAgCgotIEF3ZXNvbWUgUiAgCmh0dHBzOi8vYXdlc29tZS1yLmNvbS8gIAoKLS0tCgojIyBLZW5kaSBwYWtldCBldnJlbmluaSBvbHXFn3R1cgoKLSBwa2d2ZXJzZTogQnVpbGQgYSBNZXRhLVBhY2thZ2UgVW5pdmVyc2UgIApodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcGtndmVyc2UvaW5kZXguaHRtbAoKCi0tLQoKIyMgUiBwYWtldCB5w7xrbGVtZQoKYGBgCmluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCmluc3RhbGwucGFja2FnZXMoImptdiIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCmluc3RhbGwucGFja2FnZXMoInF1ZXN0aW9uciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCmluc3RhbGwucGFja2FnZXMoIlJjbWRyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKaW5zdGFsbC5wYWNrYWdlcygic3VtbWFyeXRvb2xzIikKYGBgCgpgYGB7ciBwYWtldCB5w7xrbGVtZX0KIyBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQojIGluc3RhbGwucGFja2FnZXMoImptdiIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiMgaW5zdGFsbC5wYWNrYWdlcygicXVlc3Rpb25yIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKIyBpbnN0YWxsLnBhY2thZ2VzKCJSY21kciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiMgaW5zdGFsbC5wYWNrYWdlcygic3VtbWFyeXRvb2xzIikKYGBgCgotLS0KCiMjIFBha2V0IMOnYcSfxLFybWEKCmBgYHtyIHBha2V0IGNhZ2lybWEsIGVycm9yPUZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZXZhbCA9IFRSVUUsIGluY2x1ZGUgPSBUUlVFfQojIHJlcXVpcmUodGlkeXZlcnNlKSAgCiMgcmVxdWlyZShqbXYpICAKIyByZXF1aXJlKHF1ZXN0aW9ucikgIAojIGxpYnJhcnkoc3VtbWFyeXRvb2xzKSAgCiMgbGlicmFyeShnZ2FuaW1hdGUpICAKYGBgCgoKCi0tLQoKIyBSIGnDp2luIHlhcmTEsW0gYnVsbWEKCgpgYGB7ciB5YXJkxLFtLCBlY2hvPVRSVUV9CiMgP21lYW4KIyA/P2VmZXRjaAojIGhlbHAobWVyZ2UpCiMgZXhhbXBsZShtZXJnZSkKYGBgCgotLS0KCi0gVmlnbmV0dGUKCiFbOnNjYWxlIDgwJV0oZmlndXJlcy92aWduZXR0ZS5wbmcpCgotLS0KCi0gUkRvY3VtZW50YXRpb24KaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnCgotIFIgUGFja2FnZSBEb2N1bWVudGF0aW9uCmh0dHBzOi8vcmRyci5pby8KCi0gR2l0SHViCgotIFN0YWNrb3ZlcmZsb3cKCmh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vCgotIEdvb2dsZSB1eWd1biBhbmFodGFyIGtlbGltZQoKLS0tCgo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+PGJsb2NrcXVvdGUgY2xhc3M9InR3aXR0ZXItdHdlZXQiIGRhdGEtbGFuZz0iZW4iPjxwIGxhbmc9ImVuIiBkaXI9Imx0ciI+SG93IEkgdXNlIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHM8L2E+IDxicj5oL3QgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9UaGVQcmFjdGljYWxEZXY/cmVmX3NyYz10d3NyYyU1RXRmdyI+QFRoZVByYWN0aWNhbERldjwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90LmNvL2VyUm5URzBVanIiPnBpYy50d2l0dGVyLmNvbS9lclJuVEcwVWpyPC9hPjwvcD4mbWRhc2g7IEVtaWx5IEJvdmVlIChAZWJvdmVlMDkpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vZWJvdmVlMDkvc3RhdHVzLzEwMjgwMzc1OTQ5NDc0ODU2OTY/cmVmX3NyYz10d3NyYyU1RXRmdyI+QXVndXN0IDEwLCAyMDE4PC9hPjwvYmxvY2txdW90ZT4KCgotLS0KCgohW10oZmlndXJlcy9Hb29nbGUtcGFja2FnZS1uYW1lLnBuZykKCi0tLQoKCgohW10oZmlndXJlcy9Hb29nbGUtc3RhcnQtd2l0aC1SLnBuZykKCgotIEdvb2dsZSdkYSBhcmFya2VuIGBbUl1gIHlhem1hayBkYSBpxZ9lIHlhcmF5YWJpbGl5b3IuCgoKLS0tCgotIHNlYXJjaGVyIHBhY2thZ2Ug8J+TpgoKClshW10oaHR0cHM6Ly9jYW1vLmdpdGh1YnVzZXJjb250ZW50LmNvbS8xMmYwZTJkMTgwNDdmMWI1ZjM2ZmJlYjA5YTFkMGU1NDgyMzY4ODNmLzY4NzQ3NDcwNzMzYTJmMmY2OTJlNjk2ZDY3NzU3MjJlNjM2ZjZkMmY1YTcxMzI3MjY3MzY0NzJlNjc2OTY2KV0oaHR0cHM6Ly9naXRodWIuY29tL2NvYXRsZXNzL3NlYXJjaGVyKQoKCgotLS0KCi0gQXdlc29tZSBDaGVhdHNoZWV0Cmh0dHBzOi8vZ2l0aHViLmNvbS9kZXRhaWx5YW5nL2F3ZXNvbWUtY2hlYXRzaGVldAoKaHR0cDovL2NyYW4uci1wcm9qZWN0Lm9yZy9kb2MvY29udHJpYi9CYWdnb3R0LXJlZmNhcmQtdjIucGRmCgpodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9yZXNvdXJjZXMvY2hlYXRzaGVldHMvCgoKLSBBd2Vzb21lIFIKCmh0dHBzOi8vZ2l0aHViLmNvbS9xaW53Zi9hd2Vzb21lLVIjcmVhZG1lCgpodHRwczovL2F3ZXNvbWUtci5jb20vCgoKLSBUd2l0dGVyCgpodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvcnN0YXRzP3NyYz1oYXNoCgotLS0KCgotIFVzZSBSZXByb2R1Y2libGUgRXhhbXBsZXMgV2hlbiBBc2tpbmcgIAoKPGJsb2NrcXVvdGUgY2xhc3M9InR3aXR0ZXItdHdlZXQiIGRhdGEtbGFuZz0iZW4iPjxwIGxhbmc9ImVuIiBkaXI9Imx0ciI+R290IGEgcXVlc3Rpb24gdG8gYXNrIG9uIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vU2xhY2tIUT9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5AU2xhY2tIUTwvYT4gb3IgcG9zdCBvbiA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2dpdGh1Yj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5AZ2l0aHViPC9hPj8gTm8gdGltZSB0byByZWFkIHRoZSBsb25nIHBvc3Qgb24gaG93IHRvIHVzZSByZXByZXg/IEhlcmUgaXMgYSAyMC1zZWNvbmQgZ2lmIGZvciB5b3UgdG8gZm9ybWF0IHlvdXIgUiBjb2RlcyBuaWNlbHkgYW5kIGZvciBvdGhlcnMgdG8gcmVwcm9kdWNlIHlvdXIgcHJvYmxlbS4gKEFuIGV4YW1wbGUgZnJvbSBhIHRhbGsgZ2l2ZW4gYnkgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9KZW5ueUJyeWFuP3JlZl9zcmM9dHdzcmMlNUV0ZnciPkBKZW5ueUJyeWFuPC9hPikgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0P3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jcnN0YXQ8L2E+IDxhIGhyZWY9Imh0dHBzOi8vdC5jby9ncHVHWHBGSXNYIj5waWMudHdpdHRlci5jb20vZ3B1R1hwRklzWDwvYT48L3A+Jm1kYXNoOyBaaGlZYW5nIChAemhpaWl5YW5nKSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL3poaWlpeWFuZy9zdGF0dXMvMTA1MzAwNjAwMzcxMTU2OTkyMD9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5PY3RvYmVyIDE4LCAyMDE4PC9hPjwvYmxvY2txdW90ZT48c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+CgoKLSBLZWVwaW5nIHVwIHRvIGRhdGUgd2l0aCBSIG5ld3MgIApodHRwczovL21hc2FsbW9uLmV1LzIwMTkvMDEvMjUvdXB0b2RhdGUvICAKCi0tLQoKIyBSc3R1ZGlvIGlsZSBwcm9qZSBvbHXFn3R1cm1hCgpodHRwczovL3N1cHBvcnQucnN0dWRpby5jb20vaGMvZW4tdXMvYXJ0aWNsZXMvMjAwNTI2MjA3LVVzaW5nLVByb2plY3RzCgohW10oaHR0cDovL3d3dy5yc3R1ZGlvLmNvbS9pbWFnZXMvZG9jcy9wcm9qZWN0c19uZXcucG5nKQoKLS0tCgojIFJTdHVkaW8gaWxlIHZlcmkgecO8a2xlbWUKCmh0dHBzOi8vc3VwcG9ydC5yc3R1ZGlvLmNvbS9oYy9lbi11cy9hcnRpY2xlcy8yMTg2MTE5NzctSW1wb3J0aW5nLURhdGEtd2l0aC1SU3R1ZGlvCgohW10oaHR0cHM6Ly9zdXBwb3J0LnJzdHVkaW8uY29tL2hjL2VuLXVzL2FydGljbGVfYXR0YWNobWVudHMvMjA2Mjc3NjE4L2RhdGEtaW1wb3J0LW92ZXJ2aWV3LmdpZikKCi0tLQoKIyMgRXhjZWwKCiMjIFNQU1MKCiMjIENTVgoKCi0tLQoKIyBWZXJpeWkgZ8O2csO8bnTDvGxlbWUKCjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD48YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5TcHJlYWRzaGVldCB1c2VycyB1c2luZyA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvcnN0YXRzP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jcnN0YXRzPC9hPjogIHdoZXJlJiMzOTtzIHRoZSBkYXRhPzxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHM8L2E+IHVzZXJzIHVzaW5nIHNwcmVhZHNoZWV0czogIHdoZXJlJiMzOTtzIHRoZSBjb2RlPzwvcD4mbWRhc2g7IExlb25hcmQgS2llZmVyIChAbGVua2llZmVyKSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2xlbmtpZWZlci9zdGF0dXMvMTAxNTU4NzQ3NTU4MDk1NjY3Mj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5KdWx5IDcsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPgoKLS0tCgojIFZlcml5aSBnw7Zyw7xudMO8bGVtZQoKYGBge3IsIHJlc3VsdHM9Im1hcmt1cCJ9CiMgbGlicmFyeShueWNmbGlnaHRzMTMpCiMgc3VtbWFyeShmbGlnaHRzKQpgYGAKCgoKYGBgClZpZXcoZGF0YSkKYGBgCgoKYGBgCmRhdGEKYGBgCgoKYGBgCmhlYWQKYGBgCgoKYGBgCnRhaWwKYGBgCgoKYGBgCmdsaW1wc2UKYGBgCgoKYGBgCnN0cgpgYGAKCgpgYGAKc2tpbXI6OnNraW0oKQpgYGAKCi0tLQoKCiMgVmVyaXlpIGRlxJ9pxZ90aXJtZQoKIyMgVmVyaXlpIGtvZCBpbGUgZGXEn2nFn3RpcmVsaW0KCiMjIFZlcml5aSBla2xlbnRpbGVybGUgZGXEn2nFn3Rpcm1lCgohWzpzY2FsZSAzMCVdKGZpZ3VyZXMvY2hhbmdlX2RhdGEucG5nKQoKCi0tLQoKCiMjIFJTdHVkaW8gYXJhY8SxbMSxxJ/EsXlsYSByZWNvZGUKCipxdWVzdGlvbnIqIHBha2V0aSBrdWxsYW7EsWxhY2FrCgohWzpzY2FsZSAzMCVdKGZpZ3VyZXMvbGV2ZWxfcmVjb2RlLnBuZykKCgotLS0KCgoKaHR0cHM6Ly9qdWJhLmdpdGh1Yi5pby9xdWVzdGlvbnIvYXJ0aWNsZXMvcmVjb2RpbmdfYWRkaW5zLmh0bWwKCgohW10oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2p1YmEvcXVlc3Rpb25yL21hc3Rlci9yZXNvdXJjZXMvc2NyZWVuc2hvdHMvaXJlY18xLnBuZykKCgotLS0KCiFbXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vanViYS9xdWVzdGlvbnIvbWFzdGVyL3Jlc291cmNlcy9zY3JlZW5zaG90cy9pcmVjXzIucG5nKQoKCi0tLQoKIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9qdWJhL3F1ZXN0aW9uci9tYXN0ZXIvcmVzb3VyY2VzL3NjcmVlbnNob3RzL2lyZWNfMy5wbmcpCgoKLS0tCgojIEJhc2l0IHRhbsSxbWxhecSxY8SxIGlzdGF0aXN0aWtsZXIKCmBgYApzdW1tYXJ5KCkKYGBgCgpgYGAKbWVhbgpgYGAKCmBgYAptZWRpYW4KYGBgCgpgYGAKbWluCmBgYAoKYGBgCm1heApgYGAKCmBgYApzZApgYGAKCmBgYAp0YWJsZSgpCmBgYAoKLS0tCgoKYGBge3IgZGVzY3JpcHRpdmUsIGVjaG89VFJVRSwgaW5jbHVkZSA9IFRSVUV9CmxpYnJhcnkocmVhZHIpCmlyaXNkYXRhIDwtIHJlYWRfY3N2KCJkYXRhL2lyaXMuY3N2IikKCmptdjo6ZGVzY3JpcHRpdmVzKAogICAgZGF0YSA9IGlyaXNkYXRhLAogICAgdmFycyA9ICJTZXBhbC5MZW5ndGgiLAogICAgc3BsaXRCeSA9ICJTcGVjaWVzIiwKICAgIGZyZXEgPSBUUlVFLAogICAgaGlzdCA9IFRSVUUsCiAgICBkZW5zID0gVFJVRSwKICAgIGJhciA9IFRSVUUsCiAgICBib3ggPSBUUlVFLAogICAgdmlvbGluID0gVFJVRSwKICAgIGRvdCA9IFRSVUUsCiAgICBtb2RlID0gVFJVRSwKICAgIHN1bSA9IFRSVUUsCiAgICBzZCA9IFRSVUUsCiAgICB2YXJpYW5jZSA9IFRSVUUsCiAgICByYW5nZSA9IFRSVUUsCiAgICBzZSA9IFRSVUUsCiAgICBza2V3ID0gVFJVRSwKICAgIGt1cnQgPSBUUlVFLAogICAgcXVhcnQgPSBUUlVFLAogICAgcGNFcUdyID0gVFJVRSkKYGBgCgotLS0KCmBgYHtyIHNjYXR0ZXIsIGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFfQojIGluc3RhbGwucGFja2FnZXMoInNjYXRyIikKc2NhdHI6OnNjYXQoCiAgICBkYXRhID0gaXJpc2RhdGEsCiAgICB4ID0gIlNlcGFsLkxlbmd0aCIsCiAgICB5ID0gIlNlcGFsLldpZHRoIiwKICAgIGdyb3VwID0gIlNwZWNpZXMiLAogICAgbWFyZyA9ICJkZW5zIiwKICAgIGxpbmUgPSAibGluZWFyIiwKICAgIHNlID0gVFJVRSkKYGBgCgotLS0KCiMjIHN1bW1hcnl0b29scwoKaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3N1bW1hcnl0b29scy92aWduZXR0ZXMvSW50cm9kdWN0aW9uLmh0bWwKCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoc3VtbWFyeXRvb2xzKQpzdW1tYXJ5dG9vbHM6OmZyZXEoaXJpcyRTcGVjaWVzLCBzdHlsZSA9ICJybWFya2Rvd24iKQpgYGAKCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CnN1bW1hcnl0b29sczo6ZnJlcShpcmlzJFNwZWNpZXMsIHJlcG9ydC5uYXMgPSBGQUxTRSwgc3R5bGUgPSAicm1hcmtkb3duIiwgaGVhZGluZ3MgPSBGQUxTRSkKYGBgCgoKLS0tCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kd2l0aCh0b2JhY2NvLCBwcmludChjdGFibGUoc21va2VyLCBkaXNlYXNlZCksIG1ldGhvZCA9ICdyZW5kZXInKSkKYGBgCgoKLS0tCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kd2l0aCh0b2JhY2NvLAogICAgIHByaW50KGN0YWJsZShzbW9rZXIsIGRpc2Vhc2VkLCBwcm9wID0gJ24nLCB0b3RhbHMgPSBGQUxTRSksCiAgICAgICAgICAgb21pdC5oZWFkaW5ncyA9IFRSVUUsIG1ldGhvZCA9ICJyZW5kZXIiKSkKYGBgCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CnN1bW1hcnl0b29sczo6ZGVzY3IoaXJpcywgc3R5bGUgPSAicm1hcmtkb3duIikKYGBgCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CmRlc2NyKGlyaXMsCiAgICAgIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpLAogICAgICB0cmFuc3Bvc2UgPSBUUlVFLAogICAgICBoZWFkaW5ncyA9IEZBTFNFLAogICAgICBzdHlsZSA9ICJybWFya2Rvd24iKQpgYGAKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KIyB2aWV3KGRmU3VtbWFyeShpcmlzKSkKCmBgYAoKCiFbXShmaWd1cmVzL2Rmc3VtbWFyeS5wbmcpCgo8IS0tIC0tLSAtLT4KCjwhLS0gYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30gLS0+CjwhLS0gZGZTdW1tYXJ5KHRvYmFjY28sIC0tPgo8IS0tICAgICAgICAgICBwbGFpbi5hc2NpaSA9IEZBTFNFLCAtLT4KPCEtLSAgICAgICAgICAgc3R5bGUgPSAiZ3JpZCIpIC0tPgo8IS0tIGBgYCAtLT4KCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CiMgRmlyc3Qgc2F2ZSB0aGUgcmVzdWx0cwppcmlzX3N0YXRzX2J5X3NwZWNpZXMgPC0gYnkoZGF0YSA9IGlyaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTkRJQ0VTID0gaXJpcyRTcGVjaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gZGVzY3IsIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3NlID0gVFJVRSkKIyBUaGVuIHVzZSB2aWV3KCksIGxpa2Ugc286CnZpZXcoaXJpc19zdGF0c19ieV9zcGVjaWVzLCBtZXRob2QgPSAicGFuZGVyIiwgc3R5bGUgPSAicm1hcmtkb3duIikKYGBgCgoKLS0tCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KIyB2aWV3KGlyaXNfc3RhdHNfYnlfc3BlY2llcykKYGBgCgohW10oZmlndXJlcy9EZXNjcmlwdGl2ZVN0YXRpc3RpY3MucG5nKQoKLS0tCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQpkYXRhKHRvYmFjY28pICMgdG9iYWNjbyBpcyBhbiBleGFtcGxlIGRhdGFmcmFtZSBpbmNsdWRlZCBpbiB0aGUgcGFja2FnZQpCTUlfYnlfYWdlIDwtIHdpdGgodG9iYWNjbywKICAgICAgICAgICAgICAgICAgIGJ5KEJNSSwgYWdlLmdyLCBkZXNjciwKICAgICAgICAgICAgICAgICAgICAgIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpKSkKdmlldyhCTUlfYnlfYWdlLCAicGFuZGVyIiwgc3R5bGUgPSAicm1hcmtkb3duIikKYGBgCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CkJNSV9ieV9hZ2UgPC0gd2l0aCh0b2JhY2NvLAogICAgICAgICAgICAgICAgICAgYnkoQk1JLCBhZ2UuZ3IsIGRlc2NyLCAgdHJhbnNwb3NlID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpKSkKCnZpZXcoQk1JX2J5X2FnZSwgInBhbmRlciIsIHN0eWxlID0gInJtYXJrZG93biIsIG9taXQuaGVhZGluZ3MgPSBUUlVFKQpgYGAKCjwhLS0gLS0tIC0tPgoKPCEtLSBgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfSAtLT4KPCEtLSB0b2JhY2NvX3N1YnNldCA8LSB0b2JhY2NvWyAsYygiZ2VuZGVyIiwgImFnZS5nciIsICJzbW9rZXIiKV0gLS0+CjwhLS0gZnJlcV90YWJsZXMgPC0gbGFwcGx5KHRvYmFjY29fc3Vic2V0LCBmcmVxKSAtLT4KCjwhLS0gIyB2aWV3KGZyZXFfdGFibGVzLCBmb290bm90ZSA9IE5BLCBmaWxlID0gJ2ZyZXEtdGFibGVzLmh0bWwnKSAtLT4KPCEtLSBgYGAgLS0+CgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CndoYXQuaXMoaXJpcykKYGBgCgo8IS0tIC0tLSAtLT4KCjwhLS0gYGBge3J9IC0tPgo8IS0tIGZyZXEodG9iYWNjbyRnZW5kZXIsIHN0eWxlID0gJ3JtYXJrZG93bicpIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS0gLS0tIC0tPgoKPCEtLSBgYGB7cn0gLS0+CjwhLS0gcHJpbnQoZnJlcSh0b2JhY2NvJGdlbmRlciksIG1ldGhvZCA9ICdyZW5kZXInKSAtLT4KPCEtLSBgYGAgLS0+CgotLS0KCiMjIHNraW1yCgpgYGAKbGlicmFyeShza2ltcikKc2tpbShkZikKYGBgCgotLS0KCiMjIERhdGFFeHBsb3JlcgoKYGBgCmxpYnJhcnkoRGF0YUV4cGxvcmVyKQpEYXRhRXhwbG9yZXI6OmNyZWF0ZV9yZXBvcnQoZGYpCmBgYAoKClshW10oaHR0cHM6Ly9zdGF0aWMxLnNxdWFyZXNwYWNlLmNvbS9zdGF0aWMvNThlZWY4ODQ2YTQ5NjNlNDI5Njg3YTRkL3QvNWJkZmMyZmI0ZDdhOWMwNGVlNTBiN2FhLzE1NDEzOTExNjA3MDIvZGF0YUV4cGxvcmVyR2lmTGcuZ2lmP2Zvcm1hdD0xNTAwdyldKGh0dHBzOi8vd3d3LmxpdHRsZW1pc3NkYXRhLmNvbS9ibG9nL3NpbXBsZS1lZGEpCgoKCi0tLQoKIyMgaW5zcGVjdGRmCgpodHRwczovL2dpdGh1Yi5jb20vYWxhc3RhaXJydXNod29ydGgvaW5zcGVjdGRmCgoKLS0tCgojIyBHcmFmaWtsZXIKCmBgYHtyIGVjaG89VFJVRX0KIyBsaWJyYXJ5KGdncGxvdDIpCiMgbGlicmFyeShtb3NhaWMpCiMgbVBsb3QoaXJpc2RhdGEpCmBgYAoKPCEtLSAtLS0gLS0+CgoKPCEtLSBgYGB7ciwgcmVzdWx0cz0iYXNpcyJ9IC0tPgo8IS0tIGN0YWJsZSh0b2JhY2NvJGdlbmRlciwgdG9iYWNjbyRzbW9rZXIsIHN0eWxlID0gJ3JtYXJrZG93bicpIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS0gLS0tIC0tPgoKCjwhLS0gYGBge3J9IC0tPgo8IS0tIHByaW50KGN0YWJsZSh0b2JhY2NvJGdlbmRlciwgdG9iYWNjbyRzbW9rZXIpLCBtZXRob2QgPSAncmVuZGVyJykgLS0+CjwhLS0gYGBgIC0tPgoKCjwhLS0gLS0tIC0tPgoKYGBgCmRlc2NyKHRvYmFjY28sIHN0eWxlID0gJ3JtYXJrZG93bicpCgpwcmludChkZXNjcih0b2JhY2NvKSwgbWV0aG9kID0gJ3JlbmRlcicsIHRhYmxlLmNsYXNzZXMgPSAnc3Qtc21hbGwnKQoKZGZTdW1tYXJ5KHRvYmFjY28sIHN0eWxlID0gJ2dyaWQnLCBwbGFpbi5hc2NpaSA9IEZBTFNFKQoKcHJpbnQoZGZTdW1tYXJ5KHRvYmFjY28sIGdyYXBoLm1hZ25pZiA9IDAuNzUpLCBtZXRob2QgPSAncmVuZGVyJykKYGBgCgoKLS0tCgoKCjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPkhlcmUsIGJ1aWxkaW5nIHVwIGEgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL2dncGxvdDI/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNnZ3Bsb3QyPC9hPiBhcyBzbG93bHkgYXMgcG9zc2libGUsIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHM8L2E+LiAgSW5jcmVtZW50YWwgYWRqdXN0bWVudHMuICA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvcnN0YXRzdGVhY2hpbmdpZGVhcz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0c3RlYWNoaW5naWRlYXM8L2E+IDxhIGhyZWY9Imh0dHBzOi8vdC5jby9uVXVsUWw4YlBoIj5waWMudHdpdHRlci5jb20vblV1bFFsOGJQaDwvYT48L3A+Jm1kYXNoOyBHaW5hIFJleW5vbGRzIChARXZhTWFlUmV5KSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL0V2YU1hZVJleS9zdGF0dXMvMTAyOTEwNDY1Njc2MzU3MjIyNj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5BdWd1c3QgMTMsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD4KCgotLS0KCgpbIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9kcmVhbVJzL2VzcXVpc3NlL21hc3Rlci9tYW4vZmlndXJlcy9lc3F1aXNzZS5naWYpXShodHRwczovL2dpdGh1Yi5jb20vZHJlYW1Scy9lc3F1aXNzZSkKCgo8YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5EcmVhbWluZyBvZiBhIGZhbmN5IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9Sc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNSc3RhdHM8L2E+IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9nZ3Bsb3Q/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNnZ3Bsb3Q8L2E+IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9kYXRhdml6P3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jZGF0YXZpejwvYT4gYnV0IHN0aWxsIHNjYXJlZCBvZiB0eXBpbmcgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL2NvZGU/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNjb2RlPC9hPj8gPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9fcHZpY3RvcnI/cmVmX3NyYz10d3NyYyU1RXRmdyI+QF9wdmljdG9ycjwvYT4gZXNxdWlzc2UgcGFja2FnZSBoYXMgeW91IGNvdmVyZWQgPGEgaHJlZj0iaHR0cHM6Ly90LmNvLzF2SURYY1ZBQUYiPmh0dHBzOi8vdC5jby8xdklEWGNWQUFGPC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vUmxUa3B0bnJOdiI+cGljLnR3aXR0ZXIuY29tL1JsVGtwdG5yTnY8L2E+PC9wPiZtZGFzaDsgUmFkb3NsYXcgUGFuY3phayAoQFJQYW5jemFrKSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL1JQYW5jemFrL3N0YXR1cy8xMDQ3MDE5NTg4NjU4MDQwODMyP3JlZl9zcmM9dHdzcmMlNUV0ZnciPk9jdG9iZXIgMiwgMjAxODwvYT48L2Jsb2NrcXVvdGU+CjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD4KCgoKPCEtLSAjIyBUYWJsb2xhciAtLT4KCgotLS0KCiMgQmF6xLEgYXJhecO8emxlcgoKaHR0cHM6Ly9zYmFsY2kuZ2l0aHViLmlvL015UkNvZGVzRm9yRGF0YUFuYWx5c2lzL1ItQXJheXV6bGVyLm5iLmh0bWwKCi0tLQoKCiMjIFJjbWRyCgpgYGAKbGlicmFyeShSY21kcikKClJjbWRyOjpDb21tYW5kZXIoKQoKYGBgCgoKLSBBIENvbXBhcmF0aXZlIFJldmlldyBvZiB0aGUgUiBDb21tYW5kZXIgR1VJIGZvciBSCgpodHRwOi8vcjRzdGF0cy5jb20vYXJ0aWNsZXMvc29mdHdhcmUtcmV2aWV3cy9yLWNvbW1hbmRlci8KCgotLS0KCiMjIGphbW92aQoKaHR0cHM6Ly93d3cuamFtb3ZpLm9yZy8KCjwhLS0gIVshW10oaHR0cHM6Ly93d3cuamFtb3ZpLm9yZy9hc3NldHMvbWFpbi1zY3JlZW5zaG90LnBuZyldKGh0dHBzOi8vd3d3LmphbW92aS5vcmcvKSAtLT4KCgpodHRwczovL2Jsb2cuamFtb3ZpLm9yZy8yMDE4LzA3LzMwL3JqLmh0bWwKCjwhLS0gIVshW10oaHR0cHM6Ly9ibG9nLmphbW92aS5vcmcvYXNzZXRzL2ltYWdlcy9yai5wbmcpXShodHRwczovL2Jsb2cuamFtb3ZpLm9yZy8yMDE4LzA3LzMwL3JqLmh0bWwpIC0tPgoKLS0tCgojIFIgbmVyZWRlbiDDtsSfcmVuaWxpcgoKaHR0cHM6Ly9zYmFsY2kuZ2l0aHViLmlvL015UkNvZGVzRm9yRGF0YUFuYWx5c2lzL1doZXJlVG9MZWFyblIubmIuaHRtbAoKLS0tCgojIFNvbnJha2kgS29udWxhcgoKLSBSU3R1ZGlvIGlsZSBHaXRIdWIga3VsbGFuxLFtxLEKLSBSIE1hcmtkb3duIHZlIFIgTm90ZWJvb2sgaWxlIHRla3JhcmxhbmFiaWxpciByYXBvcgotIEhpcG90ZXogdGVzdGxlcmkKCgoKLS0tLS0KCgojIEdlcmkgQmlsZGlyaW0KCi0gR2VyaSBiaWxkaXJpbSBpw6dpbiB0xLFrbGF5xLFuxLF6OiBfW0dlcmkgYmlsZGlyaW0gZm9ybXVdKGh0dHBzOi8vZ29vLmdsL2Zvcm1zL1lqR1o1REhndFBsUjFSbkIzKV8KCgotLS0KCgo8c2NyaXB0IGlkPSJkc3EtY291bnQtc2NyIiBzcmM9Ii8vaHR0cHMtc2JhbGNpLWdpdGh1Yi1pby5kaXNxdXMuY29tL2NvdW50LmpzIiBhc3luYz48L3NjcmlwdD4KCjxkaXYgaWQ9ImRpc3F1c190aHJlYWQiPjwvZGl2Pgo8c2NyaXB0PgoKLyoqCiogIFJFQ09NTUVOREVEIENPTkZJR1VSQVRJT04gVkFSSUFCTEVTOiBFRElUIEFORCBVTkNPTU1FTlQgVEhFIFNFQ1RJT04gQkVMT1cgVE8gSU5TRVJUIERZTkFNSUMgVkFMVUVTIEZST00gWU9VUiBQTEFURk9STSBPUiBDTVMuCiogIExFQVJOIFdIWSBERUZJTklORyBUSEVTRSBWQVJJQUJMRVMgSVMgSU1QT1JUQU5UOiBodHRwczovL2Rpc3F1cy5jb20vYWRtaW4vdW5pdmVyc2FsY29kZS8jY29uZmlndXJhdGlvbi12YXJpYWJsZXMqLwovKgp2YXIgZGlzcXVzX2NvbmZpZyA9IGZ1bmN0aW9uICgpIHsKdGhpcy5wYWdlLnVybCA9IFBBR0VfVVJMOyAgLy8gUmVwbGFjZSBQQUdFX1VSTCB3aXRoIHlvdXIgcGFnZSdzIGNhbm9uaWNhbCBVUkwgdmFyaWFibGUKdGhpcy5wYWdlLmlkZW50aWZpZXIgPSBQQUdFX0lERU5USUZJRVI7IC8vIFJlcGxhY2UgUEFHRV9JREVOVElGSUVSIHdpdGggeW91ciBwYWdlJ3MgdW5pcXVlIGlkZW50aWZpZXIgdmFyaWFibGUKfTsKKi8KKGZ1bmN0aW9uKCkgeyAvLyBET04nVCBFRElUIEJFTE9XIFRISVMgTElORQp2YXIgZCA9IGRvY3VtZW50LCBzID0gZC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsKcy5zcmMgPSAnaHR0cHM6Ly9odHRwcy1zYmFsY2ktZ2l0aHViLWlvLmRpc3F1cy5jb20vZW1iZWQuanMnOwpzLnNldEF0dHJpYnV0ZSgnZGF0YS10aW1lc3RhbXAnLCArbmV3IERhdGUoKSk7CihkLmhlYWQgfHwgZC5ib2R5KS5hcHBlbmRDaGlsZChzKTsKfSkoKTsKPC9zY3JpcHQ+Cjxub3NjcmlwdD5QbGVhc2UgZW5hYmxlIEphdmFTY3JpcHQgdG8gdmlldyB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9kaXNxdXMuY29tLz9yZWZfbm9zY3JpcHQiPmNvbW1lbnRzIHBvd2VyZWQgYnkgRGlzcXVzLjwvYT48L25vc2NyaXB0PgoKCi0tLQoKCjwhLS0gYGBgIC0tPgo8IS0tICMgU2F2ZSBGaW5hbCBEYXRhIC0tPgoKPCEtLSBzYXZlZCBkYXRhIGFmdGVyIGFuYWx5c2lzIHRvIGBEYXRhLUFmdGVyLUFuYWx5c2lzLnhsc3hgLiAtLT4KCjwhLS0gc2F2ZVJEUyhteWRhdGEsICJEYXRhLUFmdGVyLUFuYWx5c2lzLnJkcyIpIC0tPgoKPCEtLSB3cml0ZXhsOjp3cml0ZV94bHN4KG15ZGF0YSwgIkRhdGEtQWZ0ZXItQW5hbHlzaXMueGxzeCIpIC0tPgoKPCEtLSBmaWxlLmluZm8oIkRhdGEtQWZ0ZXItQW5hbHlzaXMueGxzeCIpJGN0aW1lIC0tPgoKPCEtLSBgYGAgLS0+Cgo8IS0tIC0tLSAtLT4KCgojIExpYnJhcmllcyBVc2VkCgpgYGB7cn0KY2l0YXRpb24oKQpgYGAKCmBgYApjaXRhdGlvbigidGlkeXZlcnNlIikKY2l0YXRpb24oImZvcmVpZ24iKQpjaXRhdGlvbigidGlkeWxvZyIpCmNpdGF0aW9uKCJqYW5pdG9yIikKY2l0YXRpb24oImptdiIpCmNpdGF0aW9uKCJ0YW5ncmFtIikKY2l0YXRpb24oImZpbmFsZml0IikKY2l0YXRpb24oInN1bW1hcnl0b29scyIpCmNpdGF0aW9uKCJnZ3N0YXRwbG90IikKY2l0YXRpb24oInJlYWR4bCIpCmBgYAoKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmNpdGF0aW9uKCJ0aWR5dmVyc2UiKQpjaXRhdGlvbigiZm9yZWlnbiIpCmNpdGF0aW9uKCJ0aWR5bG9nIikKY2l0YXRpb24oImphbml0b3IiKQpjaXRhdGlvbigiam12IikKY2l0YXRpb24oInRhbmdyYW0iKQpjaXRhdGlvbigiZmluYWxmaXQiKQpjaXRhdGlvbigic3VtbWFyeXRvb2xzIikKY2l0YXRpb24oImdnc3RhdHBsb3QiKQpjaXRhdGlvbigicmVhZHhsIikKYGBgCgoKPCEtLSAtLS0gLS0+CgoKPCEtLSBgYGB7ciwgcmVzdWx0cz0nYXNpcyd9IC0tPgo8IS0tIHJlcG9ydDo6Y2l0ZV9wYWNrYWdlcyhzZXNzaW9uID0gc2Vzc2lvbkluZm8oKSkgLS0+CjwhLS0gYGBgIC0tPgoKCjwhLS0gLS0tIC0tPgoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgotLS0KCgojIMSwbGV0acWfaW0gIAoKQ29tcGxldGVkIG9uIGByIFN5cy50aW1lKClgLiAgCgpTZXJkYXIgQmFsY2ksIE1ELCBQYXRob2xvZ2lzdCAgCmRyc2VyZGFyYmFsY2lAZ21haWwuY29tICAKCmh0dHBzOi8vcnB1YnMuY29tL3NiYWxjaS9DViAgIApodHRwczovL3NiYWxjaS5naXRodWIuaW8vICAKaHR0cHM6Ly9naXRodWIuY29tL3NiYWxjaSAgCmh0dHBzOi8vdHdpdHRlci5jb20vc2VyZGFyYmFsY2kKCi0tLQoKYGBge3J9CkNvbW1pdE1lc3NhZ2UgPC0gcGFzdGUoInVwZGF0ZWQgb24gIiwgU3lzLnRpbWUoKSwgc2VwID0gIiIpCgp3ZCA8LSBnZXR3ZCgpCgpnaXRDb21tYW5kIDwtIHBhc3RlKCJjZCAiLCB3ZCwgIiBcbiBnaXQgYWRkIC4gXG4gZ2l0IGNvbW1pdCAtLW1lc3NhZ2UgJyIsIENvbW1pdE1lc3NhZ2UsICInIFxuIGdpdCBwdXNoIG9yaWdpbiBtYXN0ZXIgXG4iLCBzZXAgPSAiIikKCnN5c3RlbShjb21tYW5kID0gZ2l0Q29tbWFuZCwgaW50ZXJuID0gVFJVRQopCgpgYGAKCgoKCgoKCgo=